# -*- makefile -*-
# vim:se ft=make:

ivt.o: $(TCBOFFSET)
hvt.o: $(TCBOFFSET)
tramp-mp.o: $(TCBOFFSET)

# Add future prerequisites somewhere among the list of libraries.
# You really should not have to add anything in the $(LD) line.

OBJ_KERNEL_noboot = $(filter-out bootstrap%,$(OBJ_KERNEL))
OBJ_BOOTSTRAP = $(filter  bootstrap%,$(OBJ_KERNEL))

COVFLAGS_bootstrap-gcc   := -fno-profile-arcs -fno-test-coverage
COVFLAGS_bootstrap-clang := -fno-profile-instr-generate -fno-coverage-mapping \
                            $(if $(CLANG_SUPPORTS_MCDC),-fno-coverage-mcdc)

define gen_bootstrap_flags =
CXXFLAGS_$(basename $(notdir $(1))) = \
  -fPIC $(if $(CONFIG_COV),$(COVFLAGS_bootstrap-$(CC_TYPE)))
endef

$(foreach obj,$(OBJ_BOOTSTRAP),$(eval $(call gen_bootstrap_flags, $(obj))))

-include .kernel.arm.lds.d

bootstrap_lds      = $(srcdir)/kern/arm/bootstrap.arm.ld

bootstrap_ldflags  = $(LDFLAGS) $(LD_EMULATION_FLAG)
bootstrap_ldflags += -static -pie --no-dynamic-linker -z text
bootstrap_ldflags += -defsym kernel_load_addr=$(CONFIG_KERNEL_LOAD_ADDR)
bootstrap_ldflags += -T$(bootstrap_lds)
bootstrap_ldflags += $(if $(filter clang,$(LD_TYPE)),-z rel)

bootstrap_export   = _start start_of_loader end_of_bootstrap_info
bootstrap_strip    = --strip-all $(addprefix --keep-symbol=,$(bootstrap_export))
bootstrap_syms     = end_of_bootstrap_info|_start|start_of_loader
bootstrap_sed      = 's/^0*([0-9a-f]*) [a-zA-Z] ($(bootstrap_syms))/\2 = 0x\1;/p'

bootstrap.$(KERNEL).pre.o: $(OBJ_BOOTSTRAP) $(bootstrap_lds)
	$(LINK_MESSAGE)
	$(VERBOSE)$(LD) $(bootstrap_ldflags) $(OBJ_BOOTSTRAP) -o $@

# Make a raw binary. The linker script is already minimal. Only explicitly drop
# the things that are still unneeded (dynamic symbols) and what is expected to
# come from fiasco instead (.bootstrap.dropped_info).
bootstrap.$(KERNEL).bin: bootstrap.$(KERNEL).pre.o
	$(COMP_MESSAGE)
	$(VERBOSE)$(OBJCOPY) -O binary --remove-section=.bootstrap.dropped_info \
	                     --remove-section=.dynsym \
	                     --remove-section=.dynstr $< $@

bootstrap.$(KERNEL).rel: bootstrap.$(KERNEL).bin
	$(COMP_MESSAGE)
	$(VERBOSE)$(OBJCOPY) -I binary -O $(OBJCOPY_BFDNAME) -B $(OBJCOPY_BFDARCH) \
	--rename-section .data=.bootstrap.text $< $@

# The linker will treat this file as linker script.
bootstrap.$(KERNEL).sym: bootstrap.$(KERNEL).pre.o
	$(COMP_MESSAGE)
	$(VERBOSE)$(NM) $< | sed -n -E $(bootstrap_sed) > $@

# $(1) = fiasco - variable
# $(2) = fiasco.debug - variable
# $(3) = Additional $(OBJ_X), e.g. OBJ_<unittest>
define gen_kernel_rules =
$(2): kernel.arm.lds $$(CRT0) bootstrap.$$(KERNEL).rel bootstrap.$$(KERNEL).sym $$(OBJ_KERNEL_noboot) $(3) $$(JDB) $$(KERNEL_EXTRA_LIBS) $$(LIBDISASM) $$(ABI) libdrivers.a $$(LIBUART) $$(LIBK) $$(CXXLIB) $$(LIBC) libfonts.a libgluedriverslibc.a
	$$(LINK_MESSAGE)
	$$(VERBOSE)$$(LD) $$(LDFLAGS) $$(LD_EMULATION_FLAG) $$(KERNEL_LDFLAGS) -N -defsym kernel_load_addr=$$(CONFIG_KERNEL_LOAD_ADDR) \
	-T $$< -o $$@ $$(filter-out $$<,$$+)
	$$(call ADD_CONFIGFILE,$$@)

$(1): $(2)
	$$(LINK_MESSAGE)
	$$(VERBOSE)$$(STRIP) $$< -o $$@
	$$(VERBOSE)$$(OBJCOPY) --add-gnu-debuglink=$$< $$@
	$$(VERBOSE)chmod 755 $$@
endef

# generate $(KERNEL) rule
$(eval $(call gen_kernel_rules,$(KERNEL),$(KERNEL).debug,$(OBJ_STDWORKLOAD)))

Symbols: $(KERNEL).debug
	$(COMP_MESSAGE)
	$(VERBOSE)$(NM) $(KERNEL).debug | $(CROSS_COMPILE)c++filt | sort > $@.new
	$(VERBOSE)mv $@.new $@
	$(VERBOSE)chmod 644 $@


clean-KERNEL:
	$(VERBOSE)$(RM) $(foreach s,bin rel sym,bootstrap.$(KERNEL).$(s))
